// TextMessageBubble.h
// Created by Limou on 24-8-18.
//

#ifndef FRONTEND_TEXTMESSAGEBUBBLE_HPP
#define FRONTEND_TEXTMESSAGEBUBBLE_HPP

#include <QWidget>
#include <QLabel>
#include <QPaintEvent>
#include <QFontMetrics>
#include <QPainter>
#include <QPainterPath>
#include "../../common/Common.hpp"

// >>> class TextMessageBubble begin: 文本消息气泡组件 >>>
namespace chat_system::subassembly {
    class TextMessageBubble : public QWidget {
        Q_OBJECT

    private:
        // 部件
        QLabel* textLabel_; // 气泡内部的文本消息

        // 数据
        QString content_; // 气泡内容
        bool isLeft_; // 气泡方向

    public:
        // 构造方法
        explicit TextMessageBubble(QWidget *parent = nullptr)
                : QWidget(parent)
                , textLabel_(new QLabel(this))
                , content_("")
                , isLeft_(true) {
            this->setElement(); // 设置组件
            this->setElementStyle(); // 设置组件样式
            this->setElementLayout(); // 设置组件布局
            this->setElementSignalSlot(); // 设置信号槽
        }

        // 析构方法
        ~TextMessageBubble() override = default; // TODO: 后面不使用的析构都这么做...

        // 设置内容方法
        void setContent(const QString& content) {
            content_ = content;
            this->textLabel_->setText(content_);
        }

        // 设置方向方法
        void setLeft(const bool& isLeft) {
            isLeft_ = isLeft;
        }

    protected:
        // 重写绘制事件方法
        void paintEvent(QPaintEvent* event) override {
            // 获取到父元素的宽度
            (void) event; // 消除警告
            QObject* object = this->parent();
            if (!object->isWidgetType()) {
                common::Tools::getInstance()->getInstance()->getLogger()->error("paintEvent(): The expected parent is not a QWidget.");
                return; // 当前这个对象的父元素不是预期的 QWidget, 此时不需要进行任何后续的绘制操作.
            }
            QWidget* parent = dynamic_cast<QWidget*>(object);
            int width = static_cast<int>(parent->width() * 0.6);

            // 计算当前文本宽度
            QFontMetrics metrics(this->textLabel_->font());
            int totalWidth = metrics.horizontalAdvance(this->textLabel_->text());

            // 计算出此处的行数是多少(40 表示左右各有 20px 的边距)
            int rows = (totalWidth / (width - 40)) + 1;
            if (rows == 1) {
                // 如果此时得到的行数就只有一行
                width = totalWidth + 40;
            }

            // 根据行数, 计算得到高度(20 表示上下各有 10px 的边距)
            int height = static_cast<int>(rows * (this->textLabel_->font().pixelSize() * 1.2 ) + 20);

            // 绘制圆角矩形和箭头
            QPainter painter(this);
            QPainterPath path;

            // 设置抗锯齿
            painter.setRenderHint(QPainter::Antialiasing);
            if (isLeft_) {
                painter.setPen(QPen(QColor(255, 255, 255)));
                painter.setBrush(QColor(255, 255, 255));

                // 绘制圆角矩形
                painter.drawRoundedRect(10, 0, width, height, 10, 10);
                // 绘制箭头
                path.moveTo(10, 15);
                path.lineTo(0, 20);
                path.lineTo(10, 25);
                path.closeSubpath();   // 绘制的线形成闭合的多边形, 才能进行使用 Brush 填充颜色.
                painter.drawPath(path);  // 不要忘记真正绘制操作

                this->textLabel_->setGeometry(10, 0, width, height);
            } else {
                painter.setPen(QPen(QColor(137, 217, 97)));
                painter.setBrush(QColor(137, 217, 97));

                // 圆角矩形左侧边的横坐标位置
                int leftPos = this->width() - width - 10; // 10 是用来容纳 箭头 的宽度
                // 圆角矩形右侧边的横坐标位置
                int rightPos = this->width() - 10;
                // 绘制圆角矩形
                painter.drawRoundedRect(leftPos, 0, width, height, 10, 10);
                // 绘制箭头
                path.moveTo(rightPos, 15);
                path.lineTo(rightPos + 10, 20);
                path.lineTo(rightPos, 25);
                path.closeSubpath();
                painter.drawPath(path);

                this->textLabel_->setGeometry(leftPos, 0, width, height);
            }

            // 重新设置父元素的高度, 确保父元素足够高, 能够容纳下上述绘制的消息显示的区域
            parent->setFixedHeight(height + 50); // 注意高度要涵盖之前名字和时间的 textLabel_ 的高度, 以及留点冗余空间.
        }

    private:
        // 设置组件方法
        void setElement() {
            // 设置一下 SizePolicy
            this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

            // 设置文本标签部件
            this->textLabel_->setText(content_);
            QFont font;
            font.setFamily("微软雅黑");
            font.setPixelSize(16);
            this->textLabel_->setFont(font);
            this->textLabel_->setAlignment(Qt::AlignCenter | Qt::AlignLeft);
            this->textLabel_->setWordWrap(true); // 自动换行
        }

        // 设置组件样式方法
        void setElementStyle() {
            this->setStyleSheet("QLabel { padding: 0 10px; line-height: 1.2; background-color: transparent; border: none; color: black; }"); // 1.2 是系数, 指真实文字高度为 1.2 * 16 -> 19.2, 真实行间距为 19.2 - 16 = 3.2
        }

        // 设置组件布局方法
        void setElementLayout() {

        }

        // 设置信号槽
        void setElementSignalSlot() {

        }
    };
} // namespace chat_system::subassembly end
// <<< class TextMessageBubble end <<<

#endif //FRONTEND_TEXTMESSAGEBUBBLE_HPP
